package org.posupe.empresas;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.posupe.bdr.PersistenceMechanismException;
import org.posupe.bdr.PersistenceMechanismRDBMS;
import org.posupe.bdr.TransactionException;
import org.posupe.pessoas.PessoaInexistenteException;
import org.posupe.pessoas.RepositorioPessoasBDR;
import org.posupe.util.RepositorioException;

public class RepositorioEmpresasBDR implements RepositorioEmpresas {
	private static RepositorioEmpresasBDR instance;
	
	// Consultas SQL
    private static String SQL_INSERT = "INSERT INTO EMPRESA (CODIGO,AREA) VALUES (?,?)";
    private static String SQL_REMOVE = "DELETE * FROM EMPRESA WHERE CODIGO = ?";
    private static String SQL_UPDATE = "UPDATE EMPRESA SET AREA = ? WHERE CODIGO = ?";
    private static String SQL_SELECT_WHERE = "SELECT CODIGO, AREA FROM EMPRESA WHERE CODIGO = ?";
    private static String SQL_SELECT = "SELECT CODIGO, AREA FROM EMPRESA WHERE CODIGO = ?";

	private PersistenceMechanismRDBMS pm;
	
	private RepositorioEmpresasBDR() throws RepositorioException {
		try {
			this.pm = PersistenceMechanismRDBMS.getInstance();
			this.pm.connect();
		} catch (PersistenceMechanismException e) {
			throw new RepositorioException(e);
		} 
	}
	
	public static RepositorioEmpresasBDR getInstance() throws RepositorioException {
		if (instance == null) {
			instance = new RepositorioEmpresasBDR();
		}
		return instance;
	}	
	
	public void atualizar(Empresa empresa) throws EmpresaInexistenteException,
			RepositorioException {
		try {
			pm.beginTransaction();
			RepositorioPessoasBDR.getInstance().atualizar(empresa);
			PreparedStatement ps = getStatement(SQL_UPDATE);
			ps.setInt(1, empresa.getArea().getCodigo());
			ps.execute();
			pm.commitTransaction();
		} catch (TransactionException e) {
			try {
				pm.rollbackTransaction();
			} catch (TransactionException e1) {
			}
		} catch (PessoaInexistenteException e) {
			try {
				pm.rollbackTransaction();
			} catch (TransactionException e1) {
			}
		} catch (SQLException e) {
			try {
				pm.rollbackTransaction();
			} catch (TransactionException e1) {
			}
		}
	}

	public boolean existe(String cnpj) throws RepositorioException {
		boolean resultado = false;
		
		PreparedStatement ps = getStatement(SQL_SELECT_WHERE);
		ResultSet rs = null;
		
		try {
			try {
				ps.setString(1, cnpj);			
				rs = ps.executeQuery();
				
				if (rs.next()) {
					resultado = true;
				}
			} finally {
				ps.close();
				if (rs != null) rs.close();
			}
		} catch (SQLException e) {
			throw new RepositorioException(e);
		} 

		return resultado;
	}

	public IteratorEmpresas getIterator() throws RepositorioException {
		IteratorEmpresasVector resultado = new IteratorEmpresasVector();
		
		PreparedStatement ps = getStatement(SQL_SELECT);
		ResultSet rs = null;
		
		Empresa empresa = null;
		try {
			try {
				rs = ps.executeQuery();
				
				while (rs.next()) {
					empresa = null;

					//TODO
					//carregarRepositorios(c);
					
					resultado.add(empresa);
				}
			} finally {
				ps.close();
				if (rs != null) rs.close();
			}		
		} catch (SQLException e) {
			throw new RepositorioException(e);
		} 
		
		return resultado;
	}

	public void inserir(Empresa empresa) throws RepositorioException {
		try {
			pm.beginTransaction();
			RepositorioPessoasBDR.getInstance().inserir(empresa);
			PreparedStatement ps = getStatement(SQL_INSERT);
			ps.execute();
			pm.commitTransaction();
		} catch (TransactionException e) {
			try {
				pm.rollbackTransaction();
			} catch (TransactionException e1) {
			}
		} catch (SQLException e) {
			try {
				pm.rollbackTransaction();
			} catch (TransactionException e1) {
			}
		}

	}

	public Empresa procurar(String cnpj) throws EmpresaInexistenteException,
			RepositorioException {
			Empresa resultado = null;
		
		PreparedStatement ps = getStatement(SQL_SELECT_WHERE);
		ResultSet rs = null;
		
		try {
			ps.setString(1, cnpj);			
			rs = ps.executeQuery();
			
			if (rs.next()) {
				resultado = null;
				
				//TODO carregarRepositorios(resultado);
			} else {
				throw new EmpresaInexistenteException(cnpj);
			}
		} catch (SQLException e) {
			throw new RepositorioException(e);
		} 
		
		return resultado;
	}

	public IteratorEmpresas procurar(Empresa empresa)
			throws RepositorioException {
		IteratorEmpresasVector resultado = new IteratorEmpresasVector();		
		IteratorEmpresas it = this.getIterator();
		Empresa e;
		
		while (it.hasNext()) {
			e = it.next();
			if (e.match(empresa)) {
				resultado.add(e);
			}
		}		
		
		return resultado;
	}

	public void remover(String cnpj) throws EmpresaInexistenteException,
			RepositorioException {
		try {
			pm.beginTransaction();
				RepositorioPessoasBDR.getInstance().remover(cnpj);
				PreparedStatement ps = getStatement(SQL_REMOVE);
				ps.setString(1, cnpj);
				ps.execute();
			pm.commitTransaction();
		} catch (TransactionException e) {
			try {
				pm.rollbackTransaction();
			} catch (TransactionException e1) {
			}
		} catch (SQLException e) {
			try {
				pm.rollbackTransaction();
			} catch (TransactionException e1) {
			}
		}
	}
	
	private PreparedStatement getStatement(String statement) throws RepositorioException {
		try {
			return (PreparedStatement) this.pm.getCommunicationChannel(statement);
		} catch (PersistenceMechanismException e) {
			throw new RepositorioException(e);
		}
	}


}
